/**
 * Copyright 2019 Huawei Technologies Co.,Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
 * this file except in compliance with the License.  You may obtain a copy of the
 * License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 *
 */

import {
    grants,
    objectEncryptionRule,
    optionOutput,
    owner,
    tagSet
} from "./baseModel"

export const DeleteObjects = {
    'httpMethod': 'POST',
    'urlPath': 'delete',
    'data': {
        'xmlRoot': 'Delete',
        'md5': true
    },
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Quiet': {
            'location': 'xml',
            'sentAs': 'Quiet',
        },
        'EncodingType': {
            'location': 'xml',
            'sentAs': 'EncodingType',
        },
        'Objects': {
            'required': true,
            'type': 'array',
            'location': 'xml',
            'sentAs': 'Object',
            'items': {
                'type': 'object',
                'parameters': {
                    'Key': {
                        'sentAs': 'Key',
                    },
                    'VersionId': {
                        'sentAs': 'VersionId',
                    },
                },
            },
        },
    },
}

export const DeleteObjectsOutput = {
    'data': {
        'type': 'xml',
        'xmlRoot': 'DeleteResult',
    },
    'parameters': {
        'EncodingType': {
            'location': 'xml',
            'sentAs': 'EncodingType',
        },
        'Deleteds': {
            'type': 'array',
            'location': 'xml',
            'sentAs': 'Deleted',
            'items': {
                'type': 'object',
                'parameters': {
                    'Key': {
                        'decode': true,
                        'sentAs': 'Key',
                    },
                    'VersionId': {
                        'sentAs': 'VersionId',
                    },
                    'DeleteMarker': {
                        'sentAs': 'DeleteMarker',
                    },
                    'DeleteMarkerVersionId': {
                        'sentAs': 'DeleteMarkerVersionId',
                    },
                }
            },
        },
        'Errors': {
            'type': 'array',
            'location': 'xml',
            'sentAs': 'Error',
            'items': {
                'type': 'object',
                'parameters': {
                    'Key': {
                        'decode': true,
                        'sentAs': 'Key',
                    },
                    'VersionId': {
                        'sentAs': 'VersionId',
                    },
                    'Code': {
                        'sentAs': 'Code',
                    },
                    'Message': {
                        'sentAs': 'Message',
                    },
                }
            },
        },
    },
}

export const DeleteObject = {
    'httpMethod': 'DELETE',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
    },
}

export const DeleteObjectOutput = {
    'parameters': {
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true
        },
        'DeleteMarker': {
            'location': 'header',
            'sentAs': 'delete-marker',
            'withPrefix': true
        },
    },
}

export const GetObjectTagging = {
    'httpMethod': 'GET',
    'urlPath': 'tagging',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
    }
}

export const GetObjectTaggingOutput = {
    'data': {
        'type': 'xml',
        'xmlRoot': 'Tagging',
    },
    'parameters': {
        'Tags': tagSet
    }
}

export const SetObjectTagging = {
    'httpMethod': 'PUT',
    'urlPath': 'tagging',
    'data': {
        'xmlRoot': 'Tagging',
        'md5': true
    },
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
        'Tags': tagSet
    }
}

export const DeleteObjectTagging = {
    'httpMethod': 'DELETE',
    'urlPath': 'tagging',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
    }
}

export const PutObject = {
    'httpMethod': 'PUT',
    'parameters': {
        'ObjectLockMode': {
            'location': 'header',
            'sentAs': 'object-lock-mode',
            'withPrefix': true
        },
        'ObjectLockRetainUntailDate': {
            'location': 'header',
            'sentAs': 'object-lock-retain-until-date',
            'withPrefix': true
        },
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'ContentMD5': {
            'location': 'header',
            'sentAs': 'Content-MD5',
        },
        'ContentSHA256': {
            'location': 'header',
            'sentAs': 'content-sha256',
            'withPrefix': true
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'Offset': {
            'type': 'plain'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length',
            'type': 'plain'
        },
        'Acl': {
            'location': 'header',
            'sentAs': 'acl',
            'withPrefix': true,
            'type': 'adapter'
        },
        'GrantRead': {
            'location': 'header',
            'sentAs': 'grant-read',
            'withPrefix': true,
        },
        'GrantReadAcp': {
            'location': 'header',
            'sentAs': 'grant-read-acp',
            'withPrefix': true,
        },
        'GrantWriteAcp': {
            'location': 'header',
            'sentAs': 'grant-write-acp',
            'withPrefix': true,
        },
        'GrantFullControl': {
            'location': 'header',
            'sentAs': 'grant-full-control',
            'withPrefix': true,
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
            'type': 'adapter'
        },
        'Metadata': {
            'type': 'object',
            'location': 'header',
            'sentAs': 'meta-',
            'withPrefix': true
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'Cache-Control'
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'Content-Disposition',
            'encodingSafe': ' ;/?:@&=+$,"'
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'Content-Language'
        },
        'ContentEncoding': {
            'location': 'header',
            'sentAs': 'Content-Encoding'
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
        'Tags': {
            'location': 'header',
            'sentAs': 'tagging',
            'withPrefix': true,
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'x-obs-expires',
            'type': 'number'
        },
        'SuccessActionRedirect':{
            'location' : 'header',
            'sentAs' : 'success-action-redirect'
        },
        ...objectEncryptionRule,
        'Body': {
            'location': 'body',
        },
        'SourceFile': {
            'type': 'srcFile',
        },
        'ProgressCallback': {
            'type': 'plain'
        }
    },
}

export const PutObjectOutput = {
    'parameters': {
        'ETag': {
            'location': 'header',
            'sentAs': 'etag',
        },
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true,
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
        },
        ...objectEncryptionRule,
    },
}

export const AppendObject = {
    'httpMethod': 'POST',
    'urlPath': 'append',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'Position': {
            'location': 'urlPath',
            'sentAs': 'position',
            'type': 'number'
        },
        'ContentMD5': {
            'location': 'header',
            'sentAs': 'Content-MD5',
        },
        'Offset': {
            'type': 'plain'
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length',
            'type': 'plain'
        },
        'Acl': {
            'location': 'header',
            'sentAs': 'acl',
            'withPrefix': true,
            'type': 'adapter'
        },
        'GrantRead': {
            'location': 'header',
            'sentAs': 'grant-read',
            'withPrefix': true,
        },
        'GrantReadAcp': {
            'location': 'header',
            'sentAs': 'grant-read-acp',
            'withPrefix': true,
        },
        'GrantWriteAcp': {
            'location': 'header',
            'sentAs': 'grant-write-acp',
            'withPrefix': true,
        },
        'GrantFullControl': {
            'location': 'header',
            'sentAs': 'grant-full-control',
            'withPrefix': true,
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
            'type': 'adapter'
        },
        'Metadata': {
            'type': 'object',
            'location': 'header',
            'sentAs': 'meta-',
            'withPrefix': true,
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true,
        },
        'Tags': {
            'location': 'header',
            'sentAs': 'tagging',
            'withPrefix': true,
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'x-obs-expires',
            'type': 'number'
        },
        ...objectEncryptionRule,
        'Body': {
            'location': 'body',
        },
        'SourceFile': {
            'type': 'srcFile',
        },
        'ProgressCallback': {
            'type': 'plain'
        }
    },
}

export const AppendObjectOutput = {
    'parameters': {
        'ETag': {
            'location': 'header',
            'sentAs': 'etag',
        },
        'NextPosition': {
            'location': 'header',
            'sentAs': 'next-append-position',
            'withPrefix': true,
            'type': 'number',
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
        },
        ...objectEncryptionRule,
    },
}

export const setObjectAcl = isObs => {
    return ({
        'httpMethod': 'PUT',
        'urlPath': 'acl',
        'data': {
            'xmlRoot': 'AccessControlPolicy',
        },
        'parameters': {
            'Bucket': {
                'required': true,
                'location': 'uri',
            },
            'Key': {
                'required': true,
                'location': 'uri',
            },
            'VersionId': {
                'location': 'urlPath',
                'sentAs': 'versionId',
            },
            'Acl': {
                'location': 'header',
                'sentAs': 'acl',
                'withPrefix': true,
                'type': 'adapter'
            },
            'Delivered': {
                'location': 'xml',
                'sentAs': 'Delivered'
            },
            'Owner': owner,
            'Grants': grants(isObs)
        }
    })
}

export const SetObjectAclOutput = {
    'parameters': {
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true
        },
    },
}

export const GetObjectAcl = {
    'httpMethod': 'GET',
    'urlPath': 'acl',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
    },
}

export const getObjectAclOutput = isObs => {
    return ({
        'data': {
            'type': 'xml',
            'xmlRoot': 'AccessControlPolicy',
        },
        'parameters': {
            'VersionId': {
                'location': 'header',
                'sentAs': 'version-id',
                'withPrefix': true
            },
            'Delivered': {
                'location': 'xml',
                'sentAs': 'Delivered'
            },
            'Owner': owner,
            'Grants': grants(isObs)
        }
    })
}

export const GetObject = {
    'httpMethod': 'GET',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'ResponseCacheControl': {
            'location': 'urlPath',
            'sentAs': 'response-cache-control',
        },
        'ResponseContentDisposition': {
            'location': 'urlPath',
            'sentAs': 'response-content-disposition',
        },
        'ResponseContentEncoding': {
            'location': 'urlPath',
            'sentAs': 'response-content-encoding',
        },
        'ResponseContentLanguage': {
            'location': 'urlPath',
            'sentAs': 'response-content-language',
        },
        'ResponseContentType': {
            'location': 'urlPath',
            'sentAs': 'response-content-type',
        },
        'ResponseExpires': {
            'location': 'urlPath',
            'sentAs': 'response-expires',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
        'ImageProcess': {
            'location': 'urlPath',
            'sentAs': 'x-image-process',
        },
        'IfMatch': {
            'location': 'header',
            'sentAs': 'If-Match',
        },
        'IfModifiedSince': {
            'location': 'header',
            'sentAs': 'If-Modified-Since',
        },
        'IfNoneMatch': {
            'location': 'header',
            'sentAs': 'If-None-Match',
        },
        'IfUnmodifiedSince': {
            'location': 'header',
            'sentAs': 'If-Unmodified-Since',
        },
        'Range': {
            'location': 'header',
            'sentAs': 'Range',
        },
        'Origin': {
            'location': 'header',
            'sentAs': 'Origin'
        },
        'RequestHeader': {
            'location': 'header',
            'sentAs': 'Access-Control-Request-Headers'
        },
        'SaveByType': {
            'type': 'dstType'
        },
        "SaveFilePath": {
            'type': 'dstFile'
        },
        'SseC': {
            'location': 'header',
            'sentAs': 'server-side-encryption-customer-algorithm',
            'withPrefix': true
        },
        'SseCKey': {
            'location': 'header',
            'sentAs': 'server-side-encryption-customer-key',
            'type': 'password',
            'withPrefix': true
        },
        'ProgressCallback': {
            'type': 'plain'
        }
    }
}

export const GetObjectOutput = {
    'data': {
        'type': 'body'
    },
    'parameters': {
        'Content': {
            'location': 'body',
        },
        'Expiration': {
            'location': 'header',
            'sentAs': 'expiration',
            'withPrefix': true
        },
        'ETag': {
            'location': 'header',
            'sentAs': 'etag',
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'Cache-Control',
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'Content-Disposition',
        },
        'ContentEncoding': {
            'location': 'header',
            'sentAs': 'Content-Encoding',
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'Content-Language',
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type',
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'Expires',
        },
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length',
            'type': 'number',
        },
        'DeleteMarker': {
            'location': 'header',
            'sentAs': 'delete-marker',
            'withPrefix': true,
            'type': 'boolean'
        },
        'LastModified': {
            'location': 'header',
            'sentAs': 'Last-Modified',
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true
        },
        'Restore': {
            'location': 'header',
            'sentAs': 'restore',
            'withPrefix': true
        },
        'AllowOrigin': {
            'location': 'header',
            'sentAs': 'access-control-allow-origin'
        },
        'MaxAgeSeconds': {
            'location': 'header',
            'sentAs': 'access-control-max-age',
            'type': 'number',
        },
        'ExposeHeader': {
            'location': 'header',
            'sentAs': 'access-control-expose-headers'
        },
        'AllowMethod': {
            'location': 'header',
            'sentAs': 'access-control-allow-methods'
        },
        'AllowHeader': {
            'location': 'header',
            'sentAs': 'access-control-allow-headers'
        },
        ...objectEncryptionRule,
        'Metadata': {
            'location': 'header',
            'type': 'object',
            'sentAs': 'meta-',
            'withPrefix': true
        }
    },
}

export const CopyObject = {
    'httpMethod': 'PUT',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'Acl': {
            'location': 'header',
            'sentAs': 'acl',
            'withPrefix': true,
            'type': 'adapter'
        },
        'GrantRead': {
            'location': 'header',
            'sentAs': 'grant-read',
            'withPrefix': true,
        },
        'GrantReadAcp': {
            'location': 'header',
            'sentAs': 'grant-read-acp',
            'withPrefix': true,
        },
        'GrantWriteAcp': {
            'location': 'header',
            'sentAs': 'grant-write-acp',
            'withPrefix': true,
        },
        'GrantFullControl': {
            'location': 'header',
            'sentAs': 'grant-full-control',
            'withPrefix': true,
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
            'type': 'adapter'
        },
        'CopySource': {
            'required': true,
            'location': 'header',
            'sentAs': 'copy-source',
            'withPrefix': true,
            'skipEncoding': true
        },
        'CopySourceIfMatch': {
            'location': 'header',
            'sentAs': 'copy-source-if-match',
            'withPrefix': true
        },
        'CopySourceIfModifiedSince': {
            'location': 'header',
            'sentAs': 'copy-source-if-modified-since',
            'withPrefix': true
        },
        'CopySourceIfNoneMatch': {
            'location': 'header',
            'sentAs': 'copy-source-if-none-match',
            'withPrefix': true
        },
        'CopySourceIfUnmodifiedSince': {
            'location': 'header',
            'sentAs': 'copy-source-if-unmodified-since',
            'withPrefix': true
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'ContentEncoding': {
            'location': 'header',
            'sentAs': 'content-encoding'
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'content-language'
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'content-disposition'
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'cache-control'
        },
        'TagDirective': {
            'location': 'header',
            'sentAs': 'tagging-directive',
            'withPrefix': true,
        },
        'Tags': {
            'location': 'header',
            'sentAs': 'tagging',
            'withPrefix': true,
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'expires'
        },
        'Metadata': {
            'type': 'object',
            'location': 'header',
            'sentAs': 'meta-',
            'withPrefix': true
        },
        'MetadataDirective': {
            'location': 'header',
            'sentAs': 'metadata-directive',
            'withPrefix': true
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
        'SuccessActionRedirect': {
            'location': 'header',
            'sentAs': 'success-action-redirect'
        },
        ...objectEncryptionRule,
        'CopySourceSseC': {
            'location': 'header',
            'sentAs': 'copy-source-server-side-encryption-customer-algorithm',
            'withPrefix': true
        },
        'CopySourceSseCKey': {
            'location': 'header',
            'sentAs': 'copy-source-server-side-encryption-customer-key',
            'type': 'password',
            'withPrefix': true
        },
    },
}

export const CopyObjectOutput = {
    'data': {
        'type': 'xml',
        'xmlRoot': 'CopyObjectResult',
    },
    'parameters': {
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true
        },
        'CopySourceVersionId': {
            'location': 'header',
            'sentAs': 'copy-source-version-id',
            'withPrefix': true
        },
        'ETag': {
            'location': 'xml',
            'sentAs': 'ETag',
        },
        'LastModified': {
            'location': 'xml',
            'sentAs': 'LastModified',
        },
        ...objectEncryptionRule,
    },
}

export const restoreObject = isObs => {
    const tier = isObs ? "RestoreJob" : "GlacierJobParameters";
    return ({
        'httpMethod': 'POST',
        'urlPath': 'restore',
        'data': {
            'xmlRoot': 'RestoreRequest',
            'md5': true
        },
        'parameters': {
            'Bucket': {
                'required': true,
                'location': 'uri',
            },
            'Key': {
                'required': true,
                'location': 'uri',
            },
            'VersionId': {
                'location': 'urlPath',
                'sentAs': 'versionId',
            },
            'Days': {
                'location': 'xml',
                'sentAs': 'Days',
                'type': 'number',
            },
            'Tier': {
                'wrapper': tier,
                'location': 'xml',
                'sentAs': 'Tier',
            }
        }
    })
   
}

export const GetObjectMetadata = {
    'httpMethod': 'HEAD',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId'
        },
        'Origin': {
            'location': 'header',
            'sentAs': 'Origin'
        },
        'RequestHeader': {
            'location': 'header',
            'sentAs': 'Access-Control-Request-Headers'
        },
        'SseC': {
            'location': 'header',
            'sentAs': 'server-side-encryption-customer-algorithm',
            'withPrefix': true
        },
        'SseCKey': {
            'location': 'header',
            'sentAs': 'server-side-encryption-customer-key',
            'type': 'password',
            'withPrefix': true
        }
    }
}

export const GetObjectMetadataOutput = {
    'parameters': {
        'ObjectLockMode': {
            'location': 'header',
            'sentAs': 'object-lock-mode',
            'withPrefix': true
        },
        'ObjectLockRetainUntilDate': {
            'location': 'header',
            'sentAs': 'object-lock-retain-until-date',
            'withPrefix': true
        },
        'Expiration': {
            'location': 'header',
            'sentAs': 'expiration',
            'withPrefix': true
        },
        'LastModified': {
            'location': 'header',
            'sentAs': 'Last-Modified'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length'
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'TaggingCount' : {
            'location' : 'header',
            'sentAs' : 'tagging-count',
            'withPrefix': true
        },
        'ETag': {
            'location': 'header',
            'sentAs': 'etag'
        },
        'VersionId': {
            'location': 'header',
            'sentAs': 'version-id',
            'withPrefix': true
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true
        },
        'Restore': {
            'location': 'header',
            'sentAs': 'restore',
            'withPrefix': true
        },
        'ObjectType': {
            'location': 'header',
            'sentAs': 'x-obs-object-type'
        },
        'NextPosition': {
            'location': 'header',
            'sentAs': 'x-obs-next-append-position'
        },
        'AllowOrigin': {
            'location': 'header',
            'sentAs': 'access-control-allow-origin'
        },
        'MaxAgeSeconds': {
            'location': 'header',
            'sentAs': 'access-control-max-age',
            'type': 'number',
        },
        'ExposeHeader': {
            'location': 'header',
            'sentAs': 'access-control-expose-headers'
        },
        'AllowMethod': {
            'location': 'header',
            'sentAs': 'access-control-allow-methods'
        },
        'AllowHeader': {
            'location': 'header',
            'sentAs': 'access-control-allow-headers'
        },
        ...objectEncryptionRule,
        'Metadata': {
            'location': 'header',
            'type': 'object',
            'sentAs': 'meta-',
            'withPrefix': true
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'Content-Language'
        },
        'ContentEncoding': {
            'location': 'header',
            'sentAs': 'Content-Encoding'
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'Cache-Control'
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'Content-Disposition'
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'Expires'
        },
        'ReplicationStatus': {
            'location': 'header',
            'sentAs': 'replication-status',
            'withPrefix': true
        }
    }
}

export const SetObjectMetadata = {
    'httpMethod': 'PUT',
    'urlPath': 'metadata',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId'
        },
        'Origin': {
            'location': 'header',
            'sentAs': 'Origin'
        },
        'RequestHeader': {
            'location': 'header',
            'sentAs': 'Access-Control-Request-Headers'
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'Cache-Control'
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'Content-Disposition',
            'encodingSafe': ' ;/?:@&=+$,"'
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'Content-Language'
        },
        'ContentEncoding': {
            'location': 'header',
            'sentAs': 'Content-Encoding'
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'Tags': {
            'location': 'header',
            'sentAs': 'tagging',
            'withPrefix': true
        },
        'Expires': {
            'location': 'header',
            'sentAs': 'Expires'
        },
        'Metadata': {
            'shape': 'Sy',
            'location': 'header',
            'type': 'object',
            'sentAs': 'meta-',
            'withPrefix': true
        },
        'MetadataDirective': {
            'location': 'header',
            'sentAs': 'metadata-directive',
            'withPrefix': true
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
    }
}

export const SetObjectMetadataOutput = {
    'parameters': {
        'Expires': {
            'location': 'header',
            'sentAs': 'Expires'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length'
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
        'ContentLanguage': {
            'location': 'header',
            'sentAs': 'Content-Language'
        },
        'CacheControl': {
            'location': 'header',
            'sentAs': 'Cache-Control'
        },
        'ContentDisposition': {
            'location': 'header',
            'sentAs': 'Content-Disposition'
        },
        'WebsiteRedirectLocation': {
            'location': 'header',
            'sentAs': 'website-redirect-location',
            'withPrefix': true
        },
        'StorageClass': {
            'location': 'header',
            'sentAs': 'storage-class',
            'withPrefix': true,
            'type': 'adapter'
        },
        'Metadata': {
            'location': 'header',
            'type': 'object',
            'sentAs': 'meta-',
            'withPrefix': true
        }
    }
}

export const SetObjectObjectLock = {
    'httpMethod': 'PUT',
    'urlPath': 'retention',
    'data': {
        'xmlRoot': 'Retention',
    },
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'VersionId': {
            'location': 'urlPath',
            'sentAs': 'versionId',
        },
        'Mode': {
            'sentAs': 'Mode',
            'location': 'xml'
        },
        'RetainUntilDate': {
            'sentAs': 'RetainUntilDate',
            'location': 'xml'
        },
    },
}

export const OptionsObject = {
    'httpMethod': 'OPTIONS',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri',
        },
        'Key': {
            'required': true,
            'location': 'uri',
        },
        'Origin': {
            'required': true,
            'location': 'header',
            'sentAs': 'Origin',
        },
        'AccessControlRequestMethods': {
            'required': true,
            'type': 'array',
            'location': 'header',
            'sentAs': 'Access-Control-Request-Method',
            'items': {
                'type': 'string',
            },
        },
        'AccessControlRequestHeaders': {
            'type': 'array',
            'location': 'header',
            'sentAs': 'Access-Control-Request-Headers',
            'items': {
                'type': 'string',
            },
        },
    },
}

export const OptionsObjectOutput = {
    'parameters': optionOutput
}

export const ModifyObject = {
    'httpMethod': 'PUT',
    'urlPath': 'modify',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'Body': {
            'location': 'body',
        },
        'Position': {
            'required': true,
            'location': 'urlPath',
            'sentAs': 'position'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length'
        },
        'ContentType': {
            'location': 'header',
            'sentAs': 'Content-Type'
        },
    }
}

export const ModifyObjectOutput = {
    'parameters': {
        'ETag': {
            'location': 'header',
            'sentAs': 'etag'
        }
    }
}

export const RenameObject = {
    'httpMethod': 'POST',
    'urlPath': 'rename',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'NewObjectKey': {
            'required': true,
            'location': 'urlPath',
            'sentAs': 'name'
        }
    }
}

export const RenameObjectOutput = {
    'parameters': {
        'parameters': {
            'ETag': {
                'location': 'header',
                'sentAs': 'etag'
             }
        }
    }
}

export const TruncateObject = {
    'httpMethod': 'PUT',
    'urlPath': 'truncate',
    'parameters': {
        'Bucket': {
            'required': true,
            'location': 'uri'
        },
        'Key': {
            'required': true,
            'location': 'uri'
        },
        'Length': {
            'required': true,
            'location': 'urlPath',
            'sentAs': 'length'
        },
        'ContentLength': {
            'location': 'header',
            'sentAs': 'Content-Length',
            'type': 'number',
        },
    }
}
